package com.robot.task;


import com.robot.smartqq.Receiver;
import com.robot.smartqq.callback.MessageCallback;
import com.robot.smartqq.client.SmartQQClient;
import com.robot.smartqq.model.*;
import org.apache.commons.lang.math.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;


/**
 * Created by Administrator on 2017/8/30 0030.
 */
@Component
public class StartQQ implements CommandLineRunner {

    //日志
    private final static Logger logger = LoggerFactory.getLogger(StartQQ.class);

    public static List<Friend> friendList = new ArrayList<>();                 //好友列表
    public static List<Group> groupList = new ArrayList<>();                   //群列表
    public static List<Discuss> discussList = new ArrayList<>();               //讨论组列表
    public static Map<Long, Friend> friendFromID = new HashMap<>();            //好友id到好友映射
    public static Map<Long, Group> groupFromID = new HashMap<>();              //群id到群映射
    public static Map<Long, GroupInfo> groupInfoFromID = new HashMap<>();      //群id到群详情映射
    public static Map<Long, Discuss> discussFromID = new HashMap<>();          //讨论组id到讨论组映射
    public static Map<Long, DiscussInfo> discussInfoFromID = new HashMap<>();  //讨论组id到讨论组详情映射
    public static Map<Long,Integer> userIdCount=new ConcurrentHashMap<>();
    public static List<String> listMsg=new ArrayList<>();


    private static boolean working;

    /**
     * SmartQQ客户端
     */
    public static SmartQQClient client = new SmartQQClient(new MessageCallback() {
        @Override
        public void onMessage(Message msg) {
            if (!working) {
                return;
            }
            new Thread(new Runnable() {
                @Override
                public  void run() {
                    try {
                        Thread.sleep(500 + RandomUtils.nextInt(3000));
                         Integer count=userIdCount.get(msg.getUserId());
                         if(count==null){
                             userIdCount.put(msg.getUserId(),1);
                             client.sendMessageToFriend(msg.getUserId(),listMsg.get(0));
                         }
                         else {
                             int c=count+1;
                             if(c<=listMsg.size()) {
                                 userIdCount.put(msg.getUserId(), c);
                                 client.sendMessageToFriend(msg.getUserId(),listMsg.get(c-1));
                             }
                         }

                        logger.info("[私聊] UserNick:{} userId:{} content:[{}]",getFriendNick(msg)==null?"陌生人"+msg.getUserId():getFriendNick(msg),msg.getUserId(),msg.getContent());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }).start();
        }

        @Override
        public void onGroupMessage(GroupMessage msg) {
            if (!working) {
                return;
            }
            try {
                logger.info("[群聊] UserNick:{} content:[{}]",getGroupName(msg),msg.getContent());
                //System.out.println("[" + getTime() + "] [" + getGroupName(msg) + "] " + getGroupUserNick(msg) + "：" + msg.getContent());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onDiscussMessage(DiscussMessage msg) {
            if (!working) {
                return;
            }
            try {
                System.out.println("[" + getTime() + "] [" + getDiscussName(msg) + "] " + getDiscussUserNick(msg) + "：" + msg.getContent());
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }
    );

    /**
     * 获取本地系统时间
     *
     * @return 本地系统时间
     */
    private static String getTime() {
        SimpleDateFormat time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return time.format(new Date());
    }

    /**
     * 获取群id对应群详情
     *
     * @param id 被查询的群id
     * @return 该群详情
     */
    private static GroupInfo getGroupInfoFromID(Long id) {
        if (!groupInfoFromID.containsKey(id)) {
            groupInfoFromID.put(id, client.getGroupInfo(groupFromID.get(id).getCode()));
        }
        return groupInfoFromID.get(id);
    }

    /**
     * 获取讨论组id对应讨论组详情
     *
     * @param id 被查询的讨论组id
     * @return 该讨论组详情
     */
    private static DiscussInfo getDiscussInfoFromID(Long id) {
        if (!discussInfoFromID.containsKey(id)) {
            discussInfoFromID.put(id, client.getDiscussInfo(discussFromID.get(id).getId()));
        }
        return discussInfoFromID.get(id);
    }

    /**
     * 获取群消息所在群名称
     *
     * @param msg 被查询的群消息
     * @return 该消息所在群名称
     */
    private static String getGroupName(GroupMessage msg) {
        return getGroup(msg).getName();
    }

    /**
     * 获取讨论组消息所在讨论组名称
     *
     * @param msg 被查询的讨论组消息
     * @return 该消息所在讨论组名称
     */
    private static String getDiscussName(DiscussMessage msg) {
        return getDiscuss(msg).getName();
    }

    /**
     * 获取群消息所在群
     *
     * @param msg 被查询的群消息
     * @return 该消息所在群
     */
    private static Group getGroup(GroupMessage msg) {
        return groupFromID.get(msg.getGroupId());
    }

    /**
     * 获取讨论组消息所在讨论组
     *
     * @param msg 被查询的讨论组消息
     * @return 该消息所在讨论组
     */
    private static Discuss getDiscuss(DiscussMessage msg) {
        return discussFromID.get(msg.getDiscussId());
    }

    /**
     * 获取私聊消息发送者昵称
     *
     * @param msg 被查询的私聊消息
     * @return 该消息发送者
     */
    private static String getFriendNick(Message msg) {
       Friend user = friendFromID.get(msg.getUserId());
        if(user==null){
            return null;
        }
        if (user.getMarkname() == null || user.getMarkname().equals("")) {
            return user.getNickname(); //若发送者无备注则返回其昵称
        } else {
            return user.getMarkname(); //否则返回其备注
        }

    }

    /**
     * 获取群消息发送者昵称
     *
     * @param msg 被查询的群消息
     * @return 该消息发送者昵称
     */
    private static String getGroupUserNick(GroupMessage msg) {
        for (GroupUser user : getGroupInfoFromID(msg.getGroupId()).getUsers()) {
            if (user.getUin() == msg.getUserId()) {
                if (user.getCard() == null || user.getCard().equals("")) {
                    return user.getNick(); //若发送者无群名片则返回其昵称
                } else {
                    return user.getCard(); //否则返回其群名片
                }
            }
        }
        return "系统消息"; //若在群成员列表中查询不到，则为系统消息
        //TODO: 也有可能是新加群的用户或匿名用户
    }

    /**
     * 获取讨论组消息发送者昵称
     *
     * @param msg 被查询的讨论组消息
     * @return 该消息发送者昵称
     */
    private static String getDiscussUserNick(DiscussMessage msg) {
        for (DiscussUser user : getDiscussInfoFromID(msg.getDiscussId()).getUsers()) {
            if (user.getUin() == msg.getUserId()) {
                return user.getNick(); //返回发送者昵称
            }
        }
        return "系统消息"; //若在讨论组成员列表中查询不到，则为系统消息
        //TODO: 也有可能是新加讨论组的用户
    }



    @Override
    public void run(String... strings) throws Exception {
        working = false;                                    //映射建立完毕前暂停工作以避免NullPointerException
        listMsg.add("你好!");
        listMsg.add("QQ空间有我的活动照片，想要密码的话可以帮我一个忙吗？");
        listMsg.add("手机微信点开关注公众号：efugo18 回复：密码二字就可以得到密码");
        listMsg.add("弄好了吗？我现在比较忙，加我微信号:ohcide 群里有更多的姐妹哟！");
        friendList = client.getFriendList();                //获取好友列表
        groupList = client.getGroupList();                  //获取群列表
        discussList = client.getDiscussList();
        //获取讨论组列表
        for (Friend friend : friendList) {                  //建立好友id到好友映射
            friendFromID.put(friend.getUserId(), friend);
        }
        for (Group group : groupList) {                     //建立群id到群映射
            groupFromID.put(group.getId(), group);
        }
        for (Discuss discuss : discussList) {               //建立讨论组id到讨论组映射
            discussFromID.put(discuss.getId(), discuss);
        }
        working = true;                                     //映射建立完毕后恢复工作
        //为防止请求过多导致服务器启动自我保护
        //群id到群详情映射 和 讨论组id到讨论组详情映射 将在第一次请求时创建
        //TODO: 可考虑在出现第一条讨论组消息时再建立相关映射，以防Api错误返回


    }

}
